from OWRpy import *
import os.path, redREnviron
import redRi18n
_ = redRi18n.get_(package = 'metaanalysis')

import signals
import redRGUI

#widget code
class meta(OWRpy): 
    globalSettingsList = ['commit']
    settingsList = []
    def __init__(self, **kwargs):
        OWRpy.__init__(self, **kwargs)
        self.require_librarys(["meta"])
        #python variable
        self.data = {}
        self.RFunctionParam_X = ''
        
        #Unique R variable
        self.setRvariableNames(['metaanalysis'])
        
        #Inputs
        self.inputs.addInput("X", "X", signals.base.RDataFrame, self.processobject)
        #self.inputs.addInput("Y", "Y", redRStructuredDict, self.processobject)
        
        #Outputs
        self.outputs.addOutput("Meta-analysis","Meta-analysis", signals.metaanalysis.MetaMeta) #
        
        #GUI
        self.groupBoxAll = redRGUI.base.widgetBox(self.controlArea, orientation='vertical')
        self.box = redRGUI.base.widgetBox(self.groupBoxAll)
        self.groupBoxAll.layout().setAlignment(self.box,Qt.AlignLeft)
        
        self.tableType = redRGUI.base.comboBox(self.groupBoxAll,  label = "Table type: ",
        items = [('metabin','Binary 2X2'),('metacont','Continuous')],
        editable=False, callback = self.onTableTypeChange)
        self.tableType.setCurrentId('metacont')

        ## boxes by type of analysis
        
        
        
        #############
        ## METABIN ##
        #############
        self.metabin = redRGUI.base.widgetBox(self.groupBoxAll)
        
        ### tabs
        self.metabin_tabs = redRGUI.base.tabWidget(self.metabin)
        self.metabin_tabsmodel = self.metabin_tabs.createTabPage(name = "Model",orientation='vertical')
        self.metabin_tabszeros = self.metabin_tabs.createTabPage(name = "Zeros",orientation='vertical')
        self.metabin_tabslabels = self.metabin_tabs.createTabPage(name = "Labels",orientation='vertical')        
        
        ### tab models
        self.metabin_groupBox_1 = redRGUI.base.groupBox(self.metabin_tabsmodel, orientation='horizontal', label='Table')
        self.metabin_tabsmodel_1 = redRGUI.base.widgetBox(self.metabin_groupBox_1, orientation='horizontal')
        self.metabin_treatedi = redRGUI.base.widgetBox(self.metabin_tabsmodel_1, orientation='vertical')
        self.metabin_controli = redRGUI.base.widgetBox(self.metabin_tabsmodel_1, orientation='vertical')
        self.metabin_evente = redRGUI.base.comboBox(self.metabin_treatedi, label = 'Number of events in experimental group (even.e)')
        self.metabin_ne = redRGUI.base.comboBox(self.metabin_treatedi, label = 'Number of observations in experimental group (n.e)')
        self.metabin_eventc = redRGUI.base.comboBox(self.metabin_controli, label = 'Number of events in control group (even.c)')
        self.metabin_nc = redRGUI.base.comboBox(self.metabin_controli, label = 'Number of observations in control group (n.c)')
        
        self.metabin_groupBox_2 = redRGUI.base.groupBox(self.metabin_tabsmodel, orientation='vertical', label='Grouping studies')
        self.metabin_studlab = redRGUI.base.comboBox(self.metabin_groupBox_2, label = 'Study labels')
        self.metabin_byvar_comboBox = redRGUI.base.comboBox(self.metabin_groupBox_2, label = 'Select grouping information column (byvar):')
        self.metabin_byvar_lineEdit = redRGUI.base.lineEdit(self.metabin_groupBox_2, label = 'Enter a grouping information vector (byvar). If groups are indicated in a column, leave empty.:', text='')
        self.metabin_method = redRGUI.base.radioButtons(self.metabin_tabsmodel,  label = "Method", 
        buttons = [('Inverse','Inverse'), ('MH','MH'), ('Peto','Peto')],
        setChecked='MH',orientation='horizontal', callback=self.onMetaBinMethodChange)
        self.metabin_sm = redRGUI.base.radioButtons(self.metabin_tabsmodel,  label = "Summary measure", 
        buttons = [('RR','RR'), ('OR','OR'), ('RD','RD'), ('AS','AS')],
        setChecked='RR',orientation='horizontal')
        self.metabin_model = redRGUI.base.radioButtons(self.metabin_tabsmodel,  label = "Meta-analysis", 
        buttons = [('comb.fixed','Fixed effect'), ('comb.random','Random effect'), ('both','Fixed and Random effects')],
        setChecked='comb.fixed',orientation='horizontal')
        self.metabin_print = redRGUI.base.checkBox(self.metabin_tabsmodel,  label = "Display in output", 
        buttons = [('print.byvar','Name of the grouping variable'), ('print.CMH','Cochran-Mantel-Haenszel test for overall effect')],
        setChecked='print.byvar',orientation='horizontal')
        
        ### tab zeros
        self.metabin_incr = redRGUI.base.lineEdit(self.metabin_tabszeros, label = 'Numerical value which is added to each cell frequency for studies with a zero cell count (incr):', text = '0.5')
        self.metabin_allincr = redRGUI.base.radioButtons(self.metabin_tabszeros,  label = "Addition of the incr value", 
        buttons = [('FALSE','Added only to each cell frequency of studies with a zero cell count'), ('TRUE','Added to each cell frequency of all studies if at least one study has a zero cell count.')],
        setChecked='FALSE',orientation='vertical')
        self.metabin_addincr = redRGUI.base.radioButtons(self.metabin_tabszeros,  label = "Is incr is added to each cell frequency of all studies irrespective of zero cell counts?", 
        buttons = [('FALSE','No'), ('TRUE','Yes')],
        setChecked='FALSE',orientation='horizontal')
        self.metabin_allstudies = redRGUI.base.radioButtons(self.metabin_tabszeros,  label = 'Are studies with zero or all events in both groups to be included in the meta-analysis (applies only if sm is equal to "RR" or "OR").', 
        buttons = [('FALSE','No'), ('TRUE','Yes')],
        setChecked='FALSE',orientation='horizontal')
        self.metabin_mhexact = redRGUI.base.radioButtons(self.metabin_tabszeros,  label = 'Is incr not to be added to all cell frequencies for studies with a zero cell count to calculate the pooled estimate based on the Mantel-Haenszel method.', 
        buttons = [('FALSE','No'), ('TRUE','Yes')],
        setChecked='FALSE',orientation='horizontal') 
        self.metabin_rrcochrane = redRGUI.base.radioButtons(self.metabin_tabszeros,  label = 'Is 2*incr instead of 1*incr to be added to n.e and n.c in the calculation of the relative risk (i.e., sm="RR") for studies with a zero cell.', 
        buttons = [('FALSE','No'), ('TRUE','Yes')],
        setChecked='FALSE',orientation='horizontal') 

        ### tab labels
        self.metabin_title = redRGUI.base.lineEdit(self.metabin_tabslabels, label='Title of meta-analysis / systematic review.', text = '')
        self.metabin_complab = redRGUI.base.lineEdit(self.metabin_tabslabels, label='Comparison label', text = '')
        self.metabin_outclab = redRGUI.base.lineEdit(self.metabin_tabslabels, label='Outcome label', text = '')
        self.metabin_labelE = redRGUI.base.lineEdit(self.metabin_tabslabels, label='Label for experimental group', text = 'Experimental')
        self.metabin_labelC = redRGUI.base.lineEdit(self.metabin_tabslabels, label='Label for control group.', text = 'Control')
        
        ## METABIN hidden by default ###
        self.metabin.hide()
        
        ##############
        ## METACONT ##
        ##############
        self.metacont = redRGUI.base.widgetBox(self.groupBoxAll)
        
        ### tabs
        self.metacont_tabs = redRGUI.base.tabWidget(self.metacont)
        self.metacont_tabsmodel = self.metacont_tabs.createTabPage(name = "Model",orientation='vertical')
        self.metacont_tabslabels = self.metacont_tabs.createTabPage(name = "Labels",orientation='vertical')   
        
        ### tabs Model
        self.metacont_groupBox_1 = redRGUI.base.groupBox(self.metacont_tabsmodel, orientation='horizontal', label='Table')
        self.metacont_tabsmodel_1 = redRGUI.base.widgetBox(self.metacont_groupBox_1, orientation='horizontal')
        self.metacont_treatedi = redRGUI.base.widgetBox(self.metacont_tabsmodel_1, orientation='vertical')
        self.metacont_controli = redRGUI.base.widgetBox(self.metacont_tabsmodel_1, orientation='vertical')
        self.metacont_meane = redRGUI.base.comboBox(self.metacont_treatedi, label = 'Estimated mean in experimental group (mean.e)')
        self.metacont_sde = redRGUI.base.comboBox(self.metacont_treatedi, label = 'Standard deviation in experimental group (sd.e)')
        self.metacont_ne = redRGUI.base.comboBox(self.metacont_treatedi, label = 'Number of observations in experimental group (n.e)')
        self.metacont_meanc = redRGUI.base.comboBox(self.metacont_controli, label = 'Estimated mean in control group (mean.c)')
        self.metacont_sdc = redRGUI.base.comboBox(self.metacont_controli, label = 'Standard deviation in control group (sd.c)')
        self.metacont_nc = redRGUI.base.comboBox(self.metacont_controli, label = 'Number of observations in control group (n.c)')
        
        self.metacont_groupBox_2 = redRGUI.base.groupBox(self.metacont_tabsmodel, orientation='vertical', label='Grouping studies')
        self.metacont_studlab = redRGUI.base.comboBox(self.metacont_groupBox_2, label = 'Study labels')
        self.metacont_byvar_comboBox = redRGUI.base.comboBox(self.metacont_groupBox_2, label = 'Select grouping information column (byvar):')
        self.metacont_byvar_lineEdit = redRGUI.base.lineEdit(self.metacont_groupBox_2, label = 'Enter a grouping information vector (byvar). If groups are indicated in a column, leave empty.:', text='')
        self.metacont_model = redRGUI.base.radioButtons(self.metacont_tabsmodel,  label = "Meta-analysis", 
        buttons = [('comb.fixed','Fixed effect'), ('comb.random','Random effect'), ('both','Fixed and Random effects')],
        setChecked='comb.fixed',orientation='horizontal')      
        self.metacont_sm = redRGUI.base.radioButtons(self.metacont_tabsmodel,  label = "Summary measure", 
        buttons = [('MD','Mean difference (MD)'), ('SMD','Standardized mean difference (SMD)')],
        setChecked='MD',orientation='horizontal')
        self.metacont_printbyvar = redRGUI.base.checkBox(self.metacont_tabsmodel,  label = "Display in output", 
        buttons = [('print.byvar','Name of the grouping variable')],
        setChecked='print.byvar',orientation='horizontal')
        
        ### tabs labels
        self.metacont_title = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Title of meta-analysis / systematic review (title):', text = '')
        self.metacont_complab = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Comparison label (complab):', text = '')
        self.metacont_outclab = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Outcome label (outclab):', text = '')
        self.metacont_labelE = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Label for experimental group (label.e):', text = 'Experimental')
        self.metacont_labelC = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Label for control group (label.c):', text = 'Control')
        self.metacont_bylab = redRGUI.base.lineEdit(self.metacont_tabslabels, label='Label for the grouping variable (bylab):', text = '')


        
        self.RFunctionParam_level = redRGUI.base.lineEdit(self.groupBoxAll, label='Confidence intervals for individual studies (level):', text = '0.950')
        self.RFunctionParam_levelComb = redRGUI.base.lineEdit(self.groupBoxAll, label='Confidence intervals for pooled estimates (level.comb):', text = '0.950')
        
        # Commit
        self.commit = redRGUI.base.commitButton(self.bottomAreaRight, _("Commit"), alignment=Qt.AlignLeft, 
        callback = self.commitFunction, processOnInput=True)

            
    def onTableTypeChange(self):
        self.metabin.hide()
        self.metacont.hide()
        if self.tableType.currentId() == 'metabin':
            self.metabin.show() 
        elif self.tableType.currentId() == 'metacont':
            self.metacont.show()
            
    def onMetaBinMethodChange(self):
        if self.metabin_method.getCheckedId() == 'Peto':
            self.metabin_sm.setChecked('OR')
            self.metabin_sm.setDisabled(True)
        else:
            self.metabin_sm.setEnabled(True)

    def processobject(self, data):
        
        if data:
            self.RFunctionParam_X=data.getData()
            self.data = data
            #create a list of names for combo boxes
            self.makeList_1 = [self.metabin_evente, self.metabin_ne, self.metabin_eventc, self.metabin_nc, self.metabin_studlab, self.metabin_byvar_comboBox,
            self.metacont_meane, self.metacont_sde, self.metacont_ne, self.metacont_meanc, self.metacont_sdc, self.metacont_nc, self.metacont_studlab, self.metacont_byvar_comboBox]
            for string in self.makeList_1:
                string.update(self.R('names('+self.RFunctionParam_X+')', wantType = 'list'))
            # add a None option to these combo boxes
            self.makeList_2 = [self.metabin_studlab, self.metabin_byvar_comboBox, self.metacont_studlab, self.metacont_byvar_comboBox]
            for string in self.makeList_2: 
                string.addItems(['None'])
                string.setCurrentId('None')
            if self.commit.processOnInput():
                self.commitFunction()
        else:
            self.RFunctionParam_X=''

    def commitFunction(self):
        if str(self.RFunctionParam_X) == '':
            self.status.setText('No data')
            return
        
        injection = []        
        
        #############
        ## METABIN ##
        #############
        

        if self.tableType.currentId() == 'metabin':
            len1=self.R('length(c('+unicode(self.metabin_byvar_lineEdit.text())+'))'); print '#######LEN1: ', len1
            len2=self.R('nrow('+self.RFunctionParam_X+')'); print '#######LEN2: ', len2
            ## tab models ##
            string = 'event.e='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_evente.currentId()); injection.append(string)
            string = 'n.e='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_ne.currentId()); injection.append(string)
            string = 'event.c='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_eventc.currentId()); injection.append(string)
            string = 'n.c='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_nc.currentId()); injection.append(string)
            if unicode(self.metabin_studlab.currentId()) != 'None':
                string = 'studlab='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_studlab.currentId()); injection.append(string)
            if unicode(self.metabin_byvar_lineEdit.text()) != '':
                if len1 != len2:
                    self.status.setText('Grouping information vector should contain '+str(len2)+' elements.')
                    return
                else: self.status.setText('Ok')
                string = 'byvar=c('+unicode(self.metabin_byvar_lineEdit.text())+')'; injection.append(string)
            elif unicode(self.metabin_byvar_comboBox.currentId()) != 'None':
                string = 'byvar='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metabin_byvar_comboBox.currentId()); injection.append(string)
            if self.metabin_method.getCheckedId() != '':
                string = 'method="'+unicode(self.metabin_method.getCheckedId())+'"'; injection.append(string)
            if self.metabin_sm.getCheckedId() != '':
                string = 'sm="'+unicode(self.metabin_sm.getCheckedId())+'"'; injection.append(string)
            if 'comb.fixed' in self.metabin_model.getCheckedId(): 
                string = 'comb.fixed=TRUE'
                injection.append(string)
                string = 'comb.random=FALSE'
                injection.append(string)
            elif 'comb.random' in self.metabin_model.getCheckedId(): 
                string = 'comb.fixed=FALSE'
                injection.append(string)
                string = 'comb.random=TRUE'
                injection.append(string)
            elif 'both' in self.metabin_model.getCheckedId(): 
                string = 'comb.fixed=TRUE'
                injection.append(string)
                string = 'comb.random=TRUE'
                injection.append(string)
            if 'print.byvar' in self.metabin_print.getCheckedIds(): 
                string = 'print.byvar=TRUE'
                injection.append(string)
            else : 
                string = 'print.byvar=FALSE'
                injection.append(string)
            if 'print.CMH' in self.metabin_print.getCheckedIds(): 
                string = 'print.CMH=TRUE'
                injection.append(string)
            else : 
                string = 'print.CMH=FALSE'
                injection.append(string)
            
            ## tabs zeros ##
            if unicode(self.metabin_incr.text()) != '':
                string = 'incr='+unicode(self.metabin_incr.text())+''
                injection.append(string)
            if self.metabin_allincr.getCheckedId() != '':
                string = 'allincr='+unicode(self.metabin_allincr.getCheckedId())
                injection.append(string)
            if self.metabin_addincr.getCheckedId() != '':
                string = 'addincr='+unicode(self.metabin_addincr.getCheckedId())
                injection.append(string)
            if self.metabin_allstudies.getCheckedId() != '':
                string = 'allstudies='+unicode(self.metabin_allstudies.getCheckedId())
                injection.append(string)
            if self.metabin_mhexact.getCheckedId() != '':
                string = 'MH.exact='+unicode(self.metabin_mhexact.getCheckedId())
                injection.append(string)
            if self.metabin_rrcochrane.getCheckedId() != '':
                string = 'RR.cochrane='+unicode(self.metabin_rrcochrane.getCheckedId())
                injection.append(string)
                
            ## tab labels ##
            if unicode(self.metabin_title.text()) != '':
                string = 'title="'+unicode(self.metabin_title.text())+'"'
                injection.append(string)
            if unicode(self.metabin_complab.text()) != '':
                string = 'complab="'+unicode(self.metabin_complab.text())+'"'
                injection.append(string)
            if unicode(self.metabin_outclab.text()) != '':
                string = 'outclab="'+unicode(self.metabin_outclab.text())+'"'
                injection.append(string)
            if unicode(self.metabin_labelE.text()) != '':
                string = 'label.e="'+unicode(self.metabin_labelE.text())+'"'
                injection.append(string)
            if unicode(self.metabin_labelC.text()) != '':
                string = 'label.c="'+unicode(self.metabin_labelC.text())+'"'
                injection.append(string)
            
            
            
        
        ##############
        ## METACONT ##
        ##############
        elif self.tableType.currentId() == 'metacont':
            len1=self.R('length(c('+unicode(self.metacont_byvar_lineEdit.text())+'))'); print '#######LEN1: ', len1
            len2=self.R('nrow('+self.RFunctionParam_X+')'); print '#######LEN2: ', len2
            string = 'mean.e='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_meane.currentId()); injection.append(string)
            string = 'sd.e='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_sde.currentId()); injection.append(string)
            string = 'n.e='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_ne.currentId()); injection.append(string)
            string = 'mean.c='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_meanc.currentId()); injection.append(string)
            string = 'sd.c='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_sdc.currentId()); injection.append(string)
            string = 'n.c='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_nc.currentId()); injection.append(string)
            if unicode(self.metacont_studlab.currentId()) != 'None':
                string = 'studlab='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_studlab.currentId()); injection.append(string)
            if unicode(self.metacont_byvar_lineEdit.text()) != '':
                if len1 != len2:
                    self.status.setText('Grouping information vector should contain '+str(len2)+' elements.')
                    return
                else: self.status.setText('Ok')
                string = 'byvar=c('+unicode(self.metacont_byvar_lineEdit.text())+')'; injection.append(string)
            elif unicode(self.metacont_byvar_comboBox.currentId()) != 'None':
                string = 'byvar='+unicode(self.RFunctionParam_X)+'$'+unicode(self.metacont_byvar_comboBox.currentId()); injection.append(string)
            if 'comb.fixed' in self.metacont_model.getCheckedId(): 
                string = 'comb.fixed=TRUE'
                injection.append(string)
                string = 'comb.random=FALSE'
                injection.append(string)
            elif 'comb.random' in self.metacont_model.getCheckedId(): 
                string = 'comb.fixed=FALSE'
                injection.append(string)
                string = 'comb.random=TRUE'
                injection.append(string)
            elif 'both' in self.metacont_model.getCheckedId(): 
                string = 'comb.fixed=TRUE'
                injection.append(string)
                string = 'comb.random=TRUE'
                injection.append(string)
            if self.metacont_sm.getCheckedId()=='MD': 
                string = 'sm="MD"'
                injection.append(string)
            elif self.metacont_sm.getCheckedId() == 'SMD': 
                string = 'sm="SMD"'
                injection.append(string)
            if 'print.byvar' in self.metacont_printbyvar.getCheckedIds(): 
                string = 'print.byvar=TRUE'
                injection.append(string)
            else : 
                string = 'print.byvar=FALSE'
                injection.append(string)
            if unicode(self.metacont_title.text()) != '':
                string = 'title='+unicode(self.metacont_title.text())+''
                injection.append(string)
            if unicode(self.metacont_complab.text()) != '':
                string = 'complab='+unicode(self.metacont_complab.text())+''
                injection.append(string)
            if unicode(self.metacont_outclab.text()) != '':
                string = 'outclab='+unicode(self.metacont_outclab.text())+''
                injection.append(string)
            if unicode(self.metacont_labelE.text()) != '':
                string = 'label.e="'+unicode(self.metacont_labelE.text())+'"'
                injection.append(string)
            if unicode(self.metacont_labelC.text()) != '':
                string = 'label.c="'+unicode(self.metacont_labelC.text())+'"'
                injection.append(string)
            if unicode(self.metacont_bylab.text()) != '':
                string = 'bylab="'+unicode(self.metacont_bylab.text())+'"'
                injection.append(string)
            
            
        inj = ','.join(injection)
            
        self.R(self.Rvariables['metaanalysis']+'<-'+unicode(self.tableType.currentId())+'(data='+unicode(self.RFunctionParam_X)+', '+inj+')')

        newMA = signals.metaanalysis.MetaMeta(self, data = self.Rvariables['metaanalysis'], checkVal = True)
        self.rSend("Meta-analysis", newMA)
        
